/*
 * Copyright (C) 2018 Logos Technology Ltd.
 */

package com.logos.tool;

import android.text.TextUtils;
import android.text.format.DateFormat;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class DateUtil {

    private static String[] sWeek = new String[]{"天", "一", "二", "三", "四", "五", "六"};
    private static Calendar sCalendar = Calendar.getInstance();
    private static final long ONE_SECOND = 1000;
    private static final long ONE_MINUTE = ONE_SECOND * 60;
    private static final long ONE_HOUR = ONE_MINUTE * 60;
    private static final long ONE_DAY = ONE_HOUR * 24;
    private static final int JUST = 3;
    private static final int ZERO = 0;
    private static final int MINUTE = 60;
    private static final int HOUR = 24;
    private static final int DAY = 7;

    /**
     * String 转换 Date.
     *
     * @param str    待转换格式的字符串
     * @param format 转换格式
     * @return String 转换 Date
     */
    public static Date string2Date(String str, String format) {
        try {
            return new SimpleDateFormat(format).parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return new Date();
    }

    /**
     * Date（long） 转换 String
     *
     * @param time   待转换格式的long型的date值
     * @param format 转换格式
     * @return 转换的字符串.
     */
    public static String date2String(long time, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(time);
    }

    /**
     * Date（long） 转换 String 将 long型的date值转换成格式为yyyy年MM月dd日的字符串
     *
     * @param time 待转换格式的long型的date值
     * @return yyy年MM月dd日的字符串.
     */
    public static String date2String(long time) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        return sdf.format(time);
    }

    /**
     * long 去除 时分秒
     * 时分秒全部为0.
     *
     * @param date 待转换格式的long型的date值
     * @return long 去除 时分秒时分秒全部为0.
     */
    public static long getYearMonthDay(long date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTimeInMillis();
    }

    /**
     * 获取目标时间和当前时间之间的差距.
     *
     * @param date 目标时间.
     * @return 获取目标时间和当前时间之间的差距
     */
    public static String getTimestampString(Date date) {
        Date curDate = new Date();
        long splitTime = curDate.getTime() - date.getTime();
        if (splitTime < (30 * ONE_DAY)) {
            if (splitTime < ONE_MINUTE) {
                return "刚刚";
            }
            if (splitTime < ONE_HOUR) {
                return String.format("%d分钟前", splitTime / ONE_MINUTE);
            }

            if (splitTime < ONE_DAY) {
                return String.format("%d小时前", splitTime / ONE_HOUR);
            }
            return String.format("%d天前", splitTime / ONE_DAY);
        }
        String result;
        result = "M月d日 HH:mm";
        return (new SimpleDateFormat(result, Locale.CHINA)).format(date);
    }

    /**
     * 获取目标时间和当前时间之间的差距.
     *
     * @param date 目标时间.
     * @return 获取目标时间和当前时间之间的差距
     */
    public static String getTimestampString(long date) {
        Date curDate = new Date();
        sCalendar.setTimeInMillis(date);
        int startYear = sCalendar.get(Calendar.YEAR);
        sCalendar.setTimeInMillis(curDate.getTime());
        int currentYear = sCalendar.get(Calendar.YEAR);
        if (startYear != currentYear) {
            return DateFormat.format("yyyy-MM-dd", date).toString();
        }
        long splitTime = curDate.getTime() - date;
        if (splitTime < (7 * ONE_DAY)) {
            if (splitTime < ONE_MINUTE * 3) {
                return "刚刚";
            }
            if (splitTime < ONE_HOUR) {
                return String.format("%d分钟前", splitTime / ONE_MINUTE);
            }

            if (splitTime < ONE_DAY) {
                return String.format("%d小时前", splitTime / ONE_HOUR);
            }
            return String.format("%d天前", splitTime / ONE_DAY);
        }
        return (new SimpleDateFormat("MM-dd", Locale.CHINA)).format(date);
    }

    /**
     * 获取目标时间和当前时间之间的天数差距.
     *
     * @param date 目标时间
     * @return 获取目标时间和当前时间之间的天数差距
     */
    public static int getDayStampString(long date) {
        return getDayStampString(System.currentTimeMillis(), date);
    }

    /**
     * 获取目标时间和当前时间之间的天数差距.
     * 不足一天的按一天算
     *
     * @param startDate startDate
     * @param endDate   endDate
     * @return getDayStampString
     */
    public static int getDayStampString(long startDate, long endDate) {
        long diff = endDate - startDate;
        long nd = 1000 * 24 * 60 * 60;//一天的毫秒数
        if ((diff % nd) != 0) {
            return Integer.parseInt(String.valueOf(diff / nd)) + 1;
        } else {

            return Integer.parseInt(String.valueOf(diff / nd));
        }
    }

    /**
     * 24小时制 转换 12小时制.
     *
     * @param time 目标时间
     * @return 24小时制 转换 12小时制
     */
    public static String time24To12(String time) {
        String[] str = time.split(":");
        int hour = Integer.valueOf(str[0]);
        int min = Integer.valueOf(str[1]);
        String sx;
        if (hour < 1) {
            hour = 12;
            sx = "上午";
        } else if (hour < 12) {
            sx = "上午";
        } else if (hour < 13) {
            sx = "下午";
        } else {
            sx = "下午";
            hour -= 12;
        }
        return String.format("%d:%02d%s", hour, min, sx);
    }

    /**
     * Date 转换 HH.
     *
     * @param date 目标时间
     * @return Date 转换 HH
     */
    public static String date2Hh(Date date) {
        return new SimpleDateFormat("HH").format(date);
    }

    /**
     * Date 转换 HH:mm.
     *
     * @param date 目标时间
     * @return Date 转换 HH:mm
     */
    public static String date2HhMm(Date date) {

        return new SimpleDateFormat("HH:mm").format(date);
    }

    /**
     * Date 转换 HH:mm:ss.
     *
     * @param date 目标时间
     * @return Date 转换 HH:mm:ss
     */
    public static String date2Hhmmss(Date date) {
        return new SimpleDateFormat("HH:mm:ss").format(date);
    }

    /**
     * Date 转换 yyyy-MM-dd HH:mm:ss.
     *
     * @param date 目标时间
     * @return Date 转换 yyyy-MM-dd HH:mm:ss.
     */
    public static String date2MmddHhmmss(Date date) {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
    }

    /**
     * long 转换 yyyy-MM-dd HH:mm:ss.   （毫秒）
     *
     * @param dateLong 目标时间
     * @return Date 转换 yyyy-MM-dd HH:mm:ss.
     */
    public static String dateLong2MMddHHmmss(long dateLong) {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(dateLong);
    }

    /**
     * Date 转换 MM.dd
     *
     * @param date 目标时间
     * @return Date 转换 MM.dd.
     */
    public static String date2MMdd(Date date) {
        return new SimpleDateFormat("MM.dd").format(date);
    }

    /**
     * Date 转换 yyyy.MM.dd.
     *
     * @param date 目标时间
     * @return Date 转换 yyyy.MM.dd
     */
    public static String date2yyyyMMdd(Date date) {
        return new SimpleDateFormat("yyyy年MM月dd日").format(date);
    }

    /**
     * long 型Date 转换 yyyy年MM月dd日.
     *
     * @param dateLong 目标时间
     * @return yyyy年MM月dd日.
     */
    public static String dateLong2yyyyMMdd(long dateLong) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        Date dt = new Date(dateLong);
        return sdf.format(dt);
    }

    /**
     * long 型Date 转换 yyyy年MM月dd日.
     *
     * @param dateLong 目标时间
     * @return yyyy年MM月dd日.
     */
    public static String dateLong2yyyyMMddWithBlank(long dateLong) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy 年 MM 月 dd 日");
        Date dt = new Date(dateLong);
        return sdf.format(dt);
    }

    /**
     * 将long型的date值转成指定格式.
     *
     * @param dateLong long型的date
     * @param format   指定格式.
     * @return 时间
     */
    public static String dateLong2yyyyMmDd(long dateLong, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date dt = new Date(dateLong);
        return sdf.format(dt);
    }

    /**
     * Date 转换 MM.dd
     *
     * @param dateLong 目标时间
     * @return Date 年MM月dd日.
     */
    public static String datalong2MmDd(long dateLong) {
        SimpleDateFormat sdf = new SimpleDateFormat("MM月dd日");
        Date dt = new Date(dateLong);
        return sdf.format(dt);
    }

    /**
     * Date 转换 MM.dd
     *
     * @param dateLong 目标时间
     * @return Date 年MM月dd日.
     */
    public static String datalong2yyyyMMdd(long dateLong) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date dt = new Date(dateLong);
        return sdf.format(dt);
    }

    /**
     * long 型Date 转换 yyyy年MM月dd日.
     *
     * @param dateLong 目标时间
     * @return yyyy年MM月.
     */
    public static String dateLong2yyyyMm(long dateLong) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月");
        Date dt = new Date(dateLong);
        return sdf.format(dt);
    }

    /**
     * Date 转换 MM月dd日 星期.
     *
     * @param date 目标时间
     * @return MM月dd日 星期
     */
    public static String date2MmddWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        return new SimpleDateFormat("MM月dd日 星期").format(date) + sWeek[dayOfWeek - 1];
    }

    /**
     * Date 转换 yyyy年MM月dd日 星期.
     *
     * @param date 目标时间
     * @return yyyy年MM月dd日 星期
     */
    public static String date2yyyyMmddWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        return new SimpleDateFormat("yyyy年MM月dd日 星期").format(date) + sWeek[dayOfWeek - 1];
    }

    /**
     * 比较两个日期之间相差的天数.
     *
     * @param beginDate 开始时间
     * @param endDate   结束时间
     * @return 相差天数
     */
    public static boolean checkTwoTimeDifferDay(Date beginDate, Date endDate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            beginDate = sdf.parse(sdf.format(beginDate));
            endDate = sdf.parse(sdf.format(endDate));
        } catch (Exception e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(beginDate);
        long beginTime = calendar.getTimeInMillis();
        calendar.setTime(endDate);
        long endTime = calendar.getTimeInMillis();
        long betweenDays = (endTime - beginTime) / (1000 * 3600 * 24);
        int differDay = (Integer.parseInt(String.valueOf(betweenDays))) + 1;
        return differDay > 7;
    }

    /**
     * 获得目标时间跟当前时间的时间差.
     *
     * @param createTime 目标时间
     * @return createTime ===   2016-10-31 19:59:49
     */
    public static String getDate(String createTime) {
        if (!TextUtils.isEmpty(createTime) && createTime.length() > 10) {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            long now = System.currentTimeMillis();
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(now);
            Date date = DateUtil.string2Date(createTime, "yyyy-MM-dd HH:mm:ss");
            long difference = now - date.getTime();
            int diffMinute = (int) difference / (60 * 1000);   //共计分钟数
            int diffHours = diffMinute / 60;  //共计小时数
            int diffDays = diffHours / 24;   //共计天数
//        0秒 <=  t  < 3分钟，显示为刚刚。
//        3分钟 <= t < 60分钟,  显示为 t分钟前。（3分钟前，4分钟前, 。。。。。。,59分钟前）
//        60分钟 <= t < 24小时, 显示为t小时前。（1小时前，2小时前，3小时前。。。。23小时前）
//        24小时<= t < 7天（显示 1天前，2天前，3天前。。。。。。 6天前）
//        7天<= t < 无限（不跨年的状态），显示月日，比如：10-11。
//        如果跨年显示年月日，比如 1990-10-11 。
            if (diffMinute <= JUST && diffMinute >= ZERO) {
                return "刚刚";
            } else if (diffMinute >= JUST && diffMinute < MINUTE) {
                return diffMinute + "分钟前";
            } else if (diffMinute >= MINUTE && diffHours > ZERO && diffHours < HOUR) {
                return diffHours + "小时前";
            } else if (diffHours >= HOUR && diffDays < DAY) {
                return diffDays + "天前";
            } else if (diffDays >= DAY) {
                String time = createTime.substring(0, 4);
                String currentTime = formatter.format(calendar.getTime()).substring(0, 4);
                if (!currentTime.equals(time)) {
                    return createTime;
                } else {
                    String monthDay = createTime.substring(5, 10);
                    return monthDay;
                }
            }
        }
        return "";
    }

    /**
     * isSameDay
     *
     * @param startTime start
     * @param endTime   end
     * @return boolean
     */
    public static boolean isSameDay(long startTime, long endTime) {
        return formatDateYyyyMmDd(startTime).equals(formatDateYyyyMmDd(endTime));
    }

    public static String formatDateToString(long date,String format) {

        java.text.DateFormat dateFormat = new SimpleDateFormat(format, Locale.CHINA);
        Date dt = new Date(date);
        return dateFormat.format(dt);
    }


    /**
     * 以YYYYMMDD 形式返回long date
     *
     * @param date 时间戳
     * @return 以YYYYMMDD形式时间字符串.
     */
    public static String formatDateYyyyMmDd(long date) {

        java.text.DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
        Date dt = new Date(date);
        return dateFormat.format(dt);
    }

    /**
     * 以YYYYMMDD 形式返回long date
     *
     * @param date 时间戳
     * @return 以yyyy-MM-dd HH:mm形式时间字符串.
     */
    public static String formatDateYyyyMmDdHhMm(long date) {

        java.text.DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.CHINA);
        Date dt = new Date(date);
        return dateFormat.format(dt);
    }

    /**
     * 以YYYYMMDD 形式返回long date
     *
     * @param date 时间戳
     * @return 以yyyy-MM形式时间字符串.
     */
    public static String formatDateYyyyMm(long date) {

        java.text.DateFormat dateFormat = new SimpleDateFormat("yyyy-MM", Locale.CHINA);
        Date dt = new Date(date);
        return dateFormat.format(dt);
    }

    /**
     * 字符串转Date
     *
     * @param dateString 时间字符串
     * @param format     格式化格式
     * @return Date 类型时间
     * @throws ParseException 转换异常.
     */
    public static Date stringToDate(String dateString, String format) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(format);//小写的mm表示的是分钟
        Date date = sdf.parse(dateString);
        return date;
    }

    /**
     * 获取前一天
     *
     * @param startTimeStamp 时间戳
     * @param workDays       哪一天
     * @return long类型时间.
     */
    public static long getAfterDaysStamp(long startTimeStamp, int workDays) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(startTimeStamp * 1000);
        calendar.add(Calendar.DATE, workDays - 1);
        return calendar.getTime().getTime();
    }

    /**
     * 获取月份时间戳,从每月的1号开始。
     *
     * @param timeInMilliSecond time
     * @return long类型时间.
     */
    public static long getMonthBeginMilliSeconds(long timeInMilliSecond) {
        if (timeInMilliSecond > 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(timeInMilliSecond);
            calendar.set(Calendar.MILLISECOND, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
            return calendar.getTimeInMillis();
        } else {
            return -1;
        }
    }

    /**
     * 获取月份时间戳,从每月的1号开始。
     *
     * @param timeInMilliSecond second
     * @return long类型时间.
     */
    public static long getMonthEndMilliSeconds(long timeInMilliSecond) {
        if (timeInMilliSecond > 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(timeInMilliSecond);
            calendar.set(Calendar.MILLISECOND, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.DAY_OF_MONTH,
                    calendar.getActualMaximum(Calendar.DAY_OF_MONTH));// 设置当月最后一天
            return calendar.getTimeInMillis();
        } else {
            return -1;
        }
    }

    /**
     * 日期格式字符串转换成时间戳.
     *
     * @param dateStr 字符串日期
     * @param format  如：yyyy-MM-dd HH:mm:ss
     * @return 时间戳（毫秒）
     */
    public static long date2TimeStamp(String dateStr, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            return sdf.parse(dateStr).getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }
}
